package com.mes.schedule.domain;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;

import org.hibernate.annotations.ForeignKey;

import com.mes.common.domain.BasicModel;


/**
 * 工序任务与零件任务的基类
 * date: Jun 22, 2015 2:58:05 PM <br/>  
 * @author Administrator  
 * @version   
 * @since JDK 1.6
 * @add Annotation cswen 2017/3/15
 */
@MappedSuperclass
public class STask extends BasicModel implements Serializable {
	
	
	private static final long serialVersionUID = 1L;
	
	@Column(name = "SCHEDULEUID")
	protected String scheduleUid;
	
	@Transient
	protected ScheduleScheme scheme;
	
	@Column(name = "TASKUID")
	protected String taskUid;
	
	@Column(name = "TASKNAME")
	protected String taskName;
	/**
	 * 任务状态
	 */
	@Column(name = "TASKSCHEDULESTATE")
	protected Integer taskScheduleState;
	/**
	 * 是否悬挂
	 */
	@Transient
	protected Boolean suspended;
	/**
	 * 是否关键件,改成Integer支持多个关键级别
	 */
	@Column(name="ISCRITICAL")
	protected Integer isCritical;
	
	/**
	 *  是否完成初始化
	 */
	@Transient
	protected boolean initialized;

	public boolean isInitialized() {
		return initialized;
	}

	public void setInitialized(boolean initialized) {
		this.initialized = initialized;
	}

	/**
	 *  -1--标识不进入调度，无需进入，比如分配子任务;
	 */
	public final static int TASKSCHEDULESTATE_NO= -1;//不进入调度
	/**
	 *  0--未进入调度范围;
	 */
	public final static int TASKSCHEDULESTATE_WAITING= 0;//待调度任务
	/**
	 *  1--开始调度任务;
	 */
	public final static int TASKSCHEDULESTATE_STARTED= 1;//开始调度任务
	/**
	 *  2--已成功调度任务
	 */
	public final static int TASKSCHEDULESTATE_FINISHED= 2;//已成功调度任务

	/**
	 * 任务类型
	 */		
	@Column(name = "TASKSCHEDULETYPE")
	protected Integer taskScheduleType; // 0,普通任务，来源于在制品，1--合批产生的任务，
	

	/**
	 * 零件任务--普通任务
	 */
	public final static int TASKSCHEDULETYPE_NORMAL = 0;
	/**
	 * 零件任务--合批产生的任务	
	 */
	public final static int TASKSCHEDULETYPE_COMBINEBATCH = 1;
	/**
	 * 零件任务--分批产生的任务	
	 */
	public final static int TASKSCHEDULETYPE_SPLITBATCH = 2;
	
	/**
	 * 工序任务--并行成组产生的任务	
	 */
	public final static int TASKSCHEDULETYPE_PARALLELGROUP= 3;
	/**
	 * 工序任务--串行成组产生的任务		
	 */	
	public final static int TASKSCHEDULETYPE_SERIALGROUP= 4;
//	public final static int TASKSCHEDULETYPE_OPGROUP= 4;//合并成组产生的任务	
	/**
	 * 工序任务--分拆成组产生的任务		
	 */		
	public final static int TASKSCHEDULETYPE_SUBTASK= 5;	

	/**
	 * 大纲数字
	 */
	@Transient
	protected String outlineNumber;	
	/**
	 * 大纲级别，用于支持工序成组
	 */
	@Transient
	protected String outlineLevel;	
	/**
	 * 系统色带优先级,缺省很大
	 */
	@Column(name = "PRIORITY")
	protected Integer priority=999;
	/**
	 * 用于内部计算的优先级，缺省=priority
	 */	
	@Transient
	protected Integer calPriority;
	/**
	 * 松弛系数，缺省很松
	 */		
	@Column(name = "SLACKFACTOR")
	protected Double slackFactor=999d;
	
	@Transient
	protected Integer planGrade;
	//下面以后double应该改成segment ,改成cal
	//lqm todo
	//因为在多线程中会出现前道工序修改下道工序的controlEarlyStart
	/**
	 * 因为在多线程中会出现前道工序修改下道工序的controlEarlyStart
	 */
	@Transient
	protected volatile Date controlEarlyStart;
	
	@Transient
	protected volatile int controlEarlyStartSegment;
	/**
	 * 因为在多线程中会出现前道工序修改下道工序的controlEarlyFinish
	 */
	@Transient
	protected volatile Date controlEarlyFinish;

	/**
	 * 计算必须开始时段（也必须满足工艺约束）
	 */
	@Transient
	protected Integer calMustStartSegment;
	/**
	 * 拖期惩罚代价
	 */
	@Transient
	protected Integer delayCost=300;

	/**
	 * 定义设备日历
	 */
	@Column(name = "CAL_UID")
	protected String calUid;
	
	@Transient
	protected  SCalendar calendar;
	
	@Column(name = "TASKSTATE")
	protected Integer taskState;
	/**
	 * 备份悬挂或者中断之前的任务状态。
	 */
	@Transient
	protected Integer prevTaskState;
	/**
	 * 任务类型
	 */
	@Column(name = "TASKTYPE")
	protected String taskType;	
	/**
	 * 控制结束
	 */		
	@Transient
	protected Date controlFinish;
	/**
	 * 计划数
	 */	
	@Column(name = "PLANQTY")
	protected Double planQty;
	/**
	 * 完成数
	 */
	@Column(name = "COMPLETEQTY")
	protected Double completeQty = 0d;
	/**
	 * 锁定
	 */
	@Column(name = "LOCKED", precision = 1, scale = 0)
	protected Integer locked;

	/**
	 * 专门用于计算阶段的锁定
	 */
	@Transient
	protected Integer calLocked;

	
	public Integer getCalLocked() {
		return calLocked;
	}

	public void setCalLocked(Integer calLocked) {
		this.calLocked = calLocked;
	}

	public Double getPlanQty() {
		return planQty;
	}

	public Double getCompleteQty() {
		return completeQty==null?0:completeQty;
	}

	public Integer getLocked() {
		return locked==null?0:locked;
	}

	public void setPlanQty(Double planQty) {
		this.planQty = planQty;
	}

	public void setCompleteQty(Double completeQty) {
		this.completeQty = completeQty;
	}

	public void setLocked(Integer locked) {
		this.locked = locked;
	}

	public Integer getTaskState() {
		return taskState;
	}

	public String getTaskType() {
		return taskType;
	}

	public void setTaskState(Integer taskState) {
		this.taskState = taskState;
	}

	public void setTaskType(String taskType) {
		this.taskType = taskType;
	}

	public SCalendar getCalendar() {
		return calendar;
	}

	public void setCalendar(SCalendar calendar) {
		this.calendar = calendar;
	}

	public Integer getTaskScheduleState() {
		return taskScheduleState==null?STask.TASKSCHEDULESTATE_STARTED:taskScheduleState;
	}

	public Integer getTaskScheduleType() {
		return taskScheduleType==null?STask.TASKSCHEDULETYPE_NORMAL :taskScheduleType;
	}

	public void setTaskScheduleState(Integer taskScheduleState) {
		this.taskScheduleState = taskScheduleState;
	}

	public void setTaskScheduleType(Integer taskScheduleType) {
		this.taskScheduleType = taskScheduleType;
	}
	/**
	 * @return the scheduleUid
	 */
	public String getScheduleUid() {
		return scheduleUid;
	}


	/**
	 * @param scheduleUid the scheduleUid to set
	 */
	public void setScheduleUid(String scheduleUid) {
		this.scheduleUid = scheduleUid;
	}


	/**
	 * @return the scheme
	 */
	
	public ScheduleScheme getScheme() {
		return scheme;
	}


	/**
	 * @param scheme the scheme to set
	 */
	
	public void setScheme(ScheduleScheme scheme) {
		this.scheme = scheme;
		this.scheduleUid=scheme.scheduleUid;
	}

	/**
	 * @return the taskUid
	 */
	public String getTaskUid() {
		return taskUid;
	}


	/**
	 * @param taskUid the taskUid to set
	 */
	public void setTaskUid(String taskUid) {
		this.taskUid = taskUid;
	}
	
	/**
	 * @return the taskName
	 */
	public String getTaskName() {
		return taskName;
	}

	/**
	 * @param taskName
	 *            the taskName to set
	 */
	public void setTaskName(String taskName) {
		this.taskName = taskName;
	}

	public Boolean getSuspended() {
		return suspended;
	}

	public void setSuspended(Boolean suspended) {
		this.suspended = suspended;
	}

	public String getOutlineNumber() {
		return outlineNumber;
	}

	public String getOutlineLevel() {
		return outlineLevel;
	}

	public void setOutlineNumber(String outlineNumber) {
		this.outlineNumber = outlineNumber;
	}

	public Integer getPriority() {
		return priority;
		//以后千万不要搞这种设计,会搞得需要用null时无法用
		//return priority==null?999:priority;
	}

	public Double getSlackFactor() {
		return slackFactor;
		//以后千万不要搞这种设计,会搞得需要用null时无法用
		//return slackFactor==null?999d:slackFactor;
		
	}

	public void setPriority(Integer priority) {
		this.priority = priority;
	}

	public void setSlackFactor(Double slackFactor) {
//		if(taskUid.equals("8a53bcb4-bc5c-488a-8a6e-47a99862f5c5"))
//		{
//			System.out.println("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
//		}
		this.slackFactor = slackFactor;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((taskUid == null) ? 0 : taskUid.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final STask other = (STask) obj;
		if (taskUid == null) {
			if (other.taskUid != null)
				return false;
		} else if (!taskUid.equals(other.taskUid))
			return false;
		return true;
	}

	public Integer getDelayCost() {
		return delayCost==null?300:delayCost;
	}

	public void setDelayCost(Integer delayCost) {
		this.delayCost = delayCost;
	}

	public Date getControlEarlyFinish() {
		return controlEarlyFinish;
	}

	public void setControlEarlyFinish(Date controlEarlyFinish) {
		this.controlEarlyFinish = controlEarlyFinish;
	}

	public String getCalUid() {
		return calUid;
	}

	public void setCalUid(String calUid) {
		this.calUid = calUid;
	}

	public Integer getPlanGrade() {
		return (planGrade==null||planGrade==0)?4:planGrade;
	}

	public void setPlanGrade(Integer planGrade) {
		this.planGrade = planGrade;
	}

	public Date getControlFinish() {
		return controlFinish;
	}

	public void setControlFinish(Date controlFinish) {
		this.controlFinish = controlFinish;
	}

	public Integer getCalPriority() {
		return calPriority;
	}

	public void setCalPriority(Integer calPriority) {
		this.calPriority = calPriority;
	}

	public Integer getPrevTaskState() {
		return prevTaskState;
	}

	public void setPrevTaskState(Integer prevTaskState) {
		this.prevTaskState = prevTaskState;
	}

	public Integer getIsCritical() {
		return isCritical;
	}

	public void setIsCritical(Integer isCritical) {
		this.isCritical = isCritical;
	}

	public Date getControlEarlyStart() {
		return controlEarlyStart;
	}

	public void setControlEarlyStart(Date controlEarlyStart) {
		this.controlEarlyStart = controlEarlyStart;
	}
	public Integer getCalMustStartSegment() {
		return calMustStartSegment;
	}
	public void setCalMustStartSegment(Integer calMustStartSegment) {
		this.calMustStartSegment = calMustStartSegment;
	}

	public void destroy()
	{
		if(this.scheme!=null)
		this.scheme=null;
	}
	
	public int getControlEarlyStartSegment() {
		return controlEarlyStartSegment;
	}
	public void setControlEarlyStartSegment(int controlEarlyStartSegment) {
		this.controlEarlyStartSegment = controlEarlyStartSegment;
	}


}
